hvm: Fix save/restore to handle missing pages.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Fri, 23 Feb 2007 16:17:00 +0000 (16:17 +0000)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Fri, 23 Feb 2007 16:17:00 +0000 (16:17 +0000)
Signed-off-by: Keir Fraser <keir@xensource.com>
tools/libxc/xc_hvm_restore.c
tools/libxc/xc_hvm_save.c

index ec3eeb899978160d8ae1937b8dbf529382e447b8..3d292d82ccbc1f088b31989b39914178edfd800a 100644 (file)
@@ -104,22 +104,19 @@ int xc_hvm_restore(int xc_handle, int io_fd,
     v_end = memsize << 20;
     nr_pages = (unsigned long) memsize << (20 - PAGE_SHIFT);
 
-    DPRINTF("xc_hvm_restore:dom=%d, nr_pages=0x%lx, store_evtchn=%d, *store_mfn=%ld, pae=%u, apic=%u.\n", 
+    DPRINTF("xc_hvm_restore:dom=%d, nr_pages=0x%lx, store_evtchn=%d, "
+            "*store_mfn=%ld, pae=%u, apic=%u.\n", 
             dom, nr_pages, store_evtchn, *store_mfn, pae, apic);
 
-    
     if(!get_platform_info(xc_handle, dom,
                           &max_mfn, &hvirt_start, &pt_levels)) {
         ERROR("Unable to get platform info.");
         return 1;
     }
 
-    DPRINTF("xc_hvm_restore start: nr_pages = %lx, max_pfn = %lx, max_mfn = %lx, hvirt_start=%lx, pt_levels=%d\n",
-            nr_pages,
-            max_pfn,
-            max_mfn,
-            hvirt_start,
-            pt_levels);
+    DPRINTF("xc_hvm_restore start: nr_pages = %lx, max_pfn = %lx, "
+            "max_mfn = %lx, hvirt_start=%lx, pt_levels=%d\n",
+            nr_pages, max_pfn, max_mfn, hvirt_start, pt_levels);
 
     if (mlock(&ctxt, sizeof(ctxt))) {
         /* needed for build dom0 op, but might as well do early */
@@ -220,6 +217,9 @@ int xc_hvm_restore(int xc_handle, int io_fd,
             void *page;
 
             pfn = region_pfn_type[i];
+            if ( pfn & XEN_DOMCTL_PFINFO_LTAB_MASK )
+                continue;
+
             if ( pfn > max_pfn )
             {
                 ERROR("pfn out of range");
index fdd27997439b568163ef9b4e0af078f8a9921151..c8e2b8eecba0db61a8a76cdf985922089ee7bbb5 100644 (file)
@@ -265,7 +265,7 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
 {
     xc_dominfo_t info;
 
-    int rc = 1, i, last_iter, iter = 0;
+    int rc = 1, i, j, last_iter, iter = 0;
     int live  = (flags & XCFLAGS_LIVE);
     int debug = (flags & XCFLAGS_DEBUG);
     int sent_last_iter, skip_this_iter;
@@ -289,7 +289,7 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
     /* base of the region in which domain memory is mapped */
     unsigned char *region_base = NULL;
 
-    uint32_t nr_pfns, rec_size, nr_vcpus;
+    uint32_t rec_size, nr_vcpus;
 
     /* power of 2 order of max_pfn */
     int order_nr;
@@ -360,7 +360,8 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
         goto out;
     }
 
-    DPRINTF("saved hvm domain info:max_memkb=0x%lx, max_mfn=0x%lx, nr_pages=0x%lx\n", info.max_memkb, max_mfn, info.nr_pages); 
+    DPRINTF("saved hvm domain info:max_memkb=0x%lx, max_mfn=0x%lx, "
+            "nr_pages=0x%lx\n", info.max_memkb, max_mfn, info.nr_pages); 
 
     if (live) {
         ERROR("hvm domain doesn't support live migration now.\n");
@@ -373,10 +374,6 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
             goto out;
         }
 
-        /* excludes vga acc mem */
-        /* XXX will need to check whether acceleration is enabled here! */
-        nr_pfns = info.nr_pages - 0x800;
-
         last_iter = 0;
         DPRINTF("hvm domain live migration debug start: logdirty enable.\n");
     } else {
@@ -390,20 +387,15 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
             ERROR("HVM Domain appears not to have suspended");
             goto out;
         }
-
-        nr_pfns = info.nr_pages; 
     }
 
-    DPRINTF("after 1st handle hvm domain nr_pfns=0x%x, nr_pages=0x%lx, max_memkb=0x%lx, live=%d.\n",
-            nr_pfns,
-            info.nr_pages,
-            info.max_memkb,
-            live);
+    DPRINTF("after 1st handle hvm domain nr_pages=0x%lx, "
+            "max_memkb=0x%lx, live=%d.\n",
+            info.nr_pages, info.max_memkb, live);
 
     /* Calculate the highest PFN of "normal" memory:
-     * HVM memory is sequential except for the VGA and MMIO holes, and
-     * we have nr_pfns of it (which now excludes the cirrus video RAM) */
-    max_pfn = nr_pfns; 
+     * HVM memory is sequential except for the VGA and MMIO holes. */
+    max_pfn = info.nr_pages;
     /* Skip the VGA hole from 0xa0000 to 0xc0000 */
     max_pfn += 0x20;   
     /* Skip the MMIO hole: 256MB just below 4GB */
@@ -556,9 +548,16 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
                 goto out;
             }
 
-            if (ratewrite(io_fd, region_base, PAGE_SIZE * batch) != PAGE_SIZE * batch) {
-                ERROR("ERROR when writting to state file (4)");
-                goto out;
+            for ( j = 0; j < batch; j++ )
+            {
+                if ( pfn_batch[j] & XEN_DOMCTL_PFINFO_LTAB_MASK )
+                    continue;
+                if ( ratewrite(io_fd, region_base + j*PAGE_SIZE,
+                               PAGE_SIZE) != PAGE_SIZE )
+                {
+                    ERROR("ERROR when writing to state file (4)");
+                    goto out;
+                }
             }
 
             sent_this_iter += batch;